package com.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.demo.core.constants.HttpStatus;
import com.demo.core.domain.Result;
import com.demo.core.exception.ParameterException;
import com.demo.dao.PostDao;
import com.demo.dao.UserDao;
import com.demo.domain.Post;
import com.demo.domain.ro.PageRequest;
import com.demo.domain.ro.SavePostRequest;
import com.demo.service.PostService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class PostServiceImpl extends ServiceImpl<PostDao, Post> implements PostService {

    @Autowired
    private PostDao postDao;

    @Autowired
    private UserDao userDao;

    public Result getPostByCommentCount(PageRequest pageRequest, String sortBy, String searchKeyword, int type) throws ParameterException {
        Post post = new Post();
        String orderByCommentCount = pageRequest.getOrderByCommentCount();
        int pageSize = pageRequest.getPageSize();
        int currentPage = pageRequest.getCurrentPage();
        if (currentPage == 0 || pageSize == 0) {
            throw new ParameterException("分页信息参数无效");
        }
        boolean sortByCommentCountAscending = false;
        if (orderByCommentCount.equals("asce")) {
            sortByCommentCountAscending = true;
        } else if (orderByCommentCount.equals("desc")) {
            sortByCommentCountAscending = false;
        } else {
            throw new ParameterException("排序方式参数错误");
        }
        if (type > 3 || type < 0) {
            throw new ParameterException("类型值非法");
        }

        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(searchKeyword)) {
            post.setTitle(searchKeyword);
        }
        post.setType(type);

        IPage<Post> page = null;
        if ("comments".equals(sortBy)) {
            page = getPage(currentPage, pageSize, post, sortByCommentCountAscending, "comments");
        } else if ("release_time".equals(sortBy)) {
            page = getPage(currentPage, pageSize, post, sortByCommentCountAscending, "release_time");
        } else {
            throw new ParameterException("未按要求指定排序方式");
        }

        if (currentPage > page.getPages() && page.getPages() != 0) {
            page = getPage((int) page.getPages(), pageSize, post, sortByCommentCountAscending, sortBy);
        }

        return Result.success(HttpStatus.SUCCESS, "获取数据成功", page);
    }

    //分页 标题、昵称、发布时间
    @Override
    public IPage<Post> getPage(int currentPage, int pageSize, Post post, Boolean isAscending, String sortBy) throws ParameterException {
        if (currentPage == 0 || pageSize == 0) {
            throw new ParameterException("分页信息为0");
        }
        int type = post.getType();
        LambdaQueryWrapper<Post> lqw = new LambdaQueryWrapper<Post>();
//        根据标题模糊查询帖子
        lqw.eq(Post::getType,type).like(Strings.isNotEmpty(post.getTitle()), Post::getTitle, post.getTitle());
//         如果没有指定排序方式，默认根据时间对帖子进行排序
        if (sortBy == null) {
            sortBy = "release_time";
        }
//        Comparator<Post> postComparator = null;
//        如果排序要求是升序
        if (isAscending) {
            switch (sortBy) {
//                如果是按评论进行排序
                case "comments":
                    lqw.orderByAsc(Post::getComments);
                    break;
//                    如果是按发布时间进行排序
                case "release_time":
                    lqw.orderByAsc(Post::getReleaseTime);
                    break;
                default:
                    throw new IllegalArgumentException("Invalid sort field: " + sortBy);
            }
        }
//        如果排序要求是降序
        else {
            switch (sortBy) {
                case "comments":
                    lqw.orderByDesc(Post::getComments);
                    break;
                case "release_time":
                    lqw.orderByDesc(Post::getReleaseTime);
                    break;
                default:
                    throw new IllegalArgumentException("Invalid sort field: " + sortBy);
            }
        }
        IPage<Post> page = new Page<>(currentPage, pageSize);
//        筛选符合结果的帖子并进行分页
        IPage<Post> postPage = postDao.selectPage(page, lqw);
        return postPage;

    }

    @Override
    public IPage<Post> getMyPost(int currentPage, int pageSize, Post post, Long uid)  throws ParameterException{
        if (currentPage == 0 || pageSize == 0) {
            throw new ParameterException("分页信息为0");
        }
        if (uid == null || uid < 0l) {
            throw new ParameterException("uid为空或值非法");
        }
        LambdaQueryWrapper<Post> lqw = new LambdaQueryWrapper<Post>();
//        根据标题模糊查询帖子
        lqw.eq(Post::getUid,uid);
        lqw.orderByDesc(Post::getReleaseTime);
        IPage<Post> page = new Page<>(currentPage, pageSize);
//        筛选符合结果的帖子并进行分页
        IPage<Post> myPostPage = postDao.selectPage(page, lqw);
        return myPostPage;
    }

    @Override
    public Post getPostById(Long postId) throws ParameterException {
        if (postId <= 0L) {
            throw new ParameterException("postId值非法");
        }
        Post post = postDao.selectById(postId);
        String content = post.getContent();
//        从获取的帖子对象中提取了图片URL的JSON表示并将其存储在 imageUrlsJson 变量中。
        String imageUrlsJson = post.getImageUrl();
//        将从帖子对象中提取的图片URL的JSON表示解析为一个字符串列表 imageUrls
        List<String> imageUrls = JSON.parseArray(imageUrlsJson, String.class);
//        检查是否存在图片URL
        if (imageUrls != null && !imageUrls.isEmpty()) {
            // 如果帖子包含图片URLs，将图片URLs插入到content的末尾
            for (String imageUrl : imageUrls) {
                content += "<br/><img src='" + imageUrl + "'/>";
            }
        }
        post.setContent(content);
        return post;
    }

    @Override
    public Result savePost(MultipartFile[] imageFiles, SavePostRequest savePostRequest,Long uid) throws IOException, ParameterException {
        String title = savePostRequest.getTitle();
        String unickname = savePostRequest.getUnickname();
        String content = savePostRequest.getContent();

        MultipartFile[] imageUrl = imageFiles;
        int type = savePostRequest.getType();
        if (title == null || title.isEmpty() ||
                unickname == null || unickname.isEmpty() ||
                content == null || content.isEmpty()) {
            throw new ParameterException("postRequest的必要属性含空值");
        }

        if (title.length() < 5 || title.length() > 30) {
            throw new ParameterException("标题长度超过字数限制");
        }

        // 设置内容长度限制
        int maxContentLength = 2000;
        if (content.length() > maxContentLength) {
            throw new ParameterException("帖子内容长度超过字数限制");
        }

        if (type > 3 || type < 0) {
            throw new ParameterException("类型值非法");
        }

        Post post = new Post();
        post.setTitle(title);
        post.setUnickname(unickname);
        post.setContent(content);
        post.setType(type);
        post.setUid(uid);
        boolean flag = savePostFlag(post, imageUrl);
        return flag ? Result.success(HttpStatus.SUCCESS, "添加成功", null)
                : Result.error("添加失败");
    }

    @Override
    public boolean savePostFlag(Post post, MultipartFile[] images) throws ParameterException, IOException {
        if (post == null) {
            throw new ParameterException("post为null");
        }
        if (post.getContent().equals("")) {
            throw new ParameterException("post.content为空");
        }
        if (post.getType() > 3 || post.getType() < 0) {
            throw new ParameterException("type值非法");
        }
        LocalDateTime localDateTime = LocalDateTime.now();
        post.setReleaseTime(localDateTime);
        post.setComments(0);
//        检查是否传入了图片文件
        if (images != null && images.length > 0 && !images[0].isEmpty()) {
            List<String> imageUrls = new ArrayList<>();
            for (MultipartFile image : images) {
//                    验证图片大小，如果图片大小超过5MB，抛出异常。
                if (image.getSize() > 5 * 1024 * 1024) {
                    throw new IllegalArgumentException("图片大小不能超过5MB");
                }
                String contentType = image.getContentType();
//                验证图片格式，只允许JPEG、JPG和PNG格式的图片
                if (contentType == null ||
                        (!"image/jpeg".equals(contentType) && !"image/png".equals(contentType) && !"image/jpg".equals(contentType))) {
                    throw new IllegalArgumentException("仅支持JPG、JPEG和PNG格式的图片");
                }
//                生成唯一的文件名。避免冲突
                String originalFilename = StringUtils.cleanPath(image.getOriginalFilename());
                String uniqueFilename = UUID.randomUUID().toString() + "_" + originalFilename;
//                设置图片保存路径，这里假设保存在项目的资源文件夹中
                String uploadDir = "src/main/resources/static/images/";
//                String uploadDir = System.getProperty("user.dir") + "/images/";
                Path uploadPath = Paths.get(uploadDir);
//                    如果不存在图片保存路径，进行创建
                if (!Files.exists(uploadPath)) {
                    Files.createDirectories(uploadPath);
                }
//                    构建了一个文件路径 filePath，该路径包括了保存目录和唯一的文件名 uniqueFilename
                Path filePath = uploadPath.resolve(uniqueFilename);
//                    将图片文件内容写入到刚刚构建的文件路径 filePath 中，从而实现了图片的保存操作
                Files.write(filePath, image.getBytes());
                // 设置帖子对象的图片URL为文件的相对路径
                String imageUrl = "http://localhost:8081/images/" + uniqueFilename;
                imageUrls.add(imageUrl);
            }

//                ["https://example.com/images/image1.jpg", "https://example.com/images/image2.jpg", "https://example.com/images/image3.jpg"]
            // 将图片URL列表转换为JSON格式的字符串
            String imageUrlsJson = JSON.toJSONString(imageUrls);

            // 将JSON格式的图片URLs保存到数据库中
            post.setImageUrl(imageUrlsJson);
        }
        return postDao.insert(post) > 0;

    }
}